
from typing import List, Union


class Meta:
    def __init__(self, meta_name: str, meta_content: str):
        self.meta_name = meta_name
        self.meta_content = meta_content


class Grammar:
    def __init__(self, metas: List[Meta], rules: List['Rule']):
        self.metas = metas
        self.rules = rules


class Director:
    def __init__(self, string: str):
        self.string = string


class Item:
    def __init__(
            self, value: 'Basic', alias, decoaction: Director = None):
        self.value = value
        self.alias = alias
        self.director = decoaction


# the old Item class, compatible with the old generator
class Item0:
    def __init__(self, value, item_type, alias):
        self.value = value
        self.item_type = item_type
        self.alias = alias


class Alternative:
    def __init__(self, items: List['Item'], action: 'Action'):
        self.items = items
        self.action = action


class Rule:
    def __init__(self, name: str, alts: List[List[Alternative]]):
        self.name = name
        self.alts = alts


class Action:
    def __init__(self, string: str):
        self.string = string


class Maybe:
    def __init__(self, basic: 'Basic'):
        self.basic = basic


class Lookahead:
    def __init__(self, basic: 'Basic', negative: bool):
        self.basic = basic
        self.negative = negative


class Loop:
    def __init__(self, basic: 'Basic', min_len: int):
        self.basic = basic
        self.min_len = min_len


class Basic:
    def __init__(self, value: Union[str, Alternative], type_: int):
        self.value = value
        self.type = type_


class Gather:
    def __init__(self, separator: Basic, basic: Basic):
        self.separator = separator
        self.basic = basic


class Forced:
    def __init__(self, basic: Basic):
        self.basic = basic


class Cut:
    def __init__(self):
        pass


class OldRule:
    def __init__(self, name: str, alts: List[List[str]]):
        self.name = name
        self.alts = alts


calc_rules = [
    OldRule(
        'expr',
        [['expr', "'+'", 'term'],
         ['expr', "'-'", 'term'],
         ['term']],
    ),
    OldRule(
        'term',
        [['NUMBER']],
    )
]
